#define STB_IMAGE_IMPLEMENTATION
#define STBI_NO_LINEAR
#include "stb_image.h"

#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"

#define PROGRAM "stbi_bmp2jpg"

void show_usage()
    {
    fprintf(stdout,
    "Convert image: bmp to jpg\n"
    "Usage: %s [option] <image.bmp> <image.jpg>\n"
    "Options:\n"
    "  -q<#>     image quality: [1..100] {default: 85}\n"
    "  -h        print this help\n"
    "  example: %s -q85 image.bmp image.jpg\n"
    " (note that space/s between option and its argument are not allowed)\n",
    PROGRAM, PROGRAM);
    }

int main(int argc, char *argv[])
    {
    char* progname = argv[0];
    char* ifname, *ofname;
    int ofoverwrite = 0;

    int im_width, im_height, im_channels, im_cpp, im_quality = 85;
    void *pixels = NULL;

    while((argc>1) && (*argv[1]=='-'))
        {
        for(int i=1; argv[1][i]!='\0'; i++)
            {
            switch (argv[1][i])
                {
                case '0':
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9':
                break;
                case 'q':
                    if((argv[1][i+1]!='\0') && (argv[1][i+1]>='0') && (argv[1][i+1]<='9'))
                        {
                        im_quality = atoi(&argv[1][i+1]);
                        if((im_quality < 0) || (im_quality > 100))
                            {
                            printf("quality=%d out of range\n", im_quality);
                            return 1;
                            }
                        }
                    else
                        {
                        printf("invalid quality='%s'\n", &argv[1][i+1]);
                        return 1;
                        }
                    break;
                case 'f':
                    ofoverwrite = 1;
                    break;
                case 'h':
                    show_usage();
                    return 0;
                    break;
                default:
                    fprintf(stderr, "Unknown option '-%c'\n", argv[1][i]);
                    return 1;
                    }
                }
        argc--;
        argv++;
        }

    if(argc<3)
        {
        printf("Not enough arguments. Check help.\n");
        show_usage();
        return 0;
        }
    ifname = argv[1];
    ofname = argv[2];
    if(strcmp(ifname, ofname) == 0)
        {
        fprintf(stdout, "Input and output are the same file: '%s'.\n", ifname);
        return 1;
        }
    if(!ofoverwrite)
        {
        FILE* fy = fopen(ofname, "rb");
        if (fy)
            {
            fclose(fy);
            fprintf(stderr, "File '%s' already exists. Try `-f' to overwrite.\n", ofname);
            return 1;
            }
        }


        if(!stbi_info(ifname, &im_width, &im_height, &im_channels))
            {
            printf("Couldn't read header %s\n", ifname);
            return 1;
            }
        pixels = (void *)stbi_load(ifname, &im_width, &im_height, &im_cpp, im_channels);

    if(pixels == NULL)
        {
        printf("Couldn't load/decode %s\n", ifname);
        return 1;
        }

    int encoded = 0;
        {
        encoded = stbi_write_jpg(ofname, im_width, im_height, im_cpp, pixels, im_quality);
        }
    if(!encoded)
        {
        printf("Couldn't write/encode %s\n", ofname);
        return 1;
        }

    free(pixels);

    return 0;
}
